const phantom = require('phantom');
const cheerio = require('cheerio');
const fs = require("fs");
const csv = require('fast-csv');

// 爬取页面地址,第一页
const URL_PREFIX = "https://list.jd.com/list.html?cat=737,794,870&page="
const URL_SUFFIX = "&stock=0&sort=sort_rank_asc&trans=1&JL=4_7_0#J_main";

const Pa = async() => {
    const instance_getnum = await phantom.create(['--ignore-ssl-errors=yes', '--load-images=no']);
    const page_getnum = await instance_getnum.createPage();
    await page_getnum.open(URL_PREFIX + "1" + URL_SUFFIX);
    const listhref = [];
    //禁用详细页面的javascript以提高速度，所以以下三个内容必须从列表页读取了，故定义数组保存
    const list价格 = [];
    const list累计评价 = [];
    const list选购指数 = [];

    var csvStream = csv
        .createWriteStream({
            headers: true
        })
        .transform(function (row) {
            return {
                //基本信息
                名称: row.a,
                价格: row.b,
                累计评价: row.c,
                选购指数: row.d,
                //主体
                品牌: row.e,
                系列: row.f,
                型号: row.g,
                颜色: row.h,
                类别: row.i,
                // 功能
                制冷类型: row.j,
                匹数: row.k,
                "定频/变频": row.l,
                能效等级: row.m,
                电辅加热: row.n,
                "适用面积(平方米)": row.o,
                "制冷量(W)": row.p,
                "制冷功率(W)": row.q,
                "制热量(W)": row.r,
                "制热功率(W)": row.s,
                "电辅加热功率(W)": row.t,
                "内机噪音(dB(A)": row.u,
                "外机噪音(dB(A)": row.v,
                变频机能效比: row.w,
                "循环风量(m3/h)": row.x,
                "除湿量(×10-3m3/h)": row.y,
                扫风方式: row.z,
                //产品特色
                自动清洁: row.aa,
                静音设计: row.ab,
                独立除湿: row.ac,
                除甲醛: row.ad,
                其它: row.ae,
                //规格
                制冷剂: row.af,
                "电压/频率（V/HZ）": row.ag,
                "内机尺寸（宽x高x深）mm": row.ah,
                "外机尺寸（宽x高x深）mm": row.ai,
                "电压/频率（V/HZ）": row.aj,
                "内机重量（kg）": row.ak,
                "外机重量（kg)": row.al,
                //规格
                特性: row.am
            };
        }),
        writableStream = fs.createWriteStream("京东空调信息.csv");

    writableStream.on("finish", function () {
        console.log("全部数据抓取完毕！");
    });
    await csvStream.pipe(writableStream);
    await page_getnum.on('onResourceRequested', true, function (requestData) {});
    const content = await page_getnum.property('content');
    const tmp$ = cheerio.load(content);
    var pagenumhtml = tmp$('.p-skip').html();
    pagenumhtml = cheerio.load(pagenumhtml);
    var PAGETOTALNUM = pagenumhtml('b').text();
    await page_getnum.close();
    await instance_getnum.exit();
    var page, pageitem;
    for (var l = 84; l < PAGETOTALNUM; l++) {
        console.log("开始读取第" + (l + 1) + "页列表信息")
        const instance = await phantom.create(['--ignore-ssl-errors=yes', '--load-images=no']);
        page = await instance.createPage();
        var status = await page.open(URL_PREFIX + (l + 1) + URL_SUFFIX);
        while (status != "success") {
            await pageitem.close();
            console.log("网页暂时打不开，重试中..")
            status = await page.open(URL_PREFIX + (l + 1) + URL_SUFFIX);
        }
        const content = await page.property('content');
        const $ = await cheerio.load(content);
        //找所有的list
        await $('.gl-item').each(function (i, elem) {
            const li = cheerio.load($(this).html());
            listhref[i] = "http:" + li(".comment").attr("href");
            if (li('.js_ys').html() != null) {
                list价格[i] = li('.js_ys').text().replace("¥", "");
            }
            if (li('.comment').html() != null) {
                list累计评价[i] = li('.comment').text();
            }
            if (li('.buy-score').html() != null) {
                list选购指数[i] = li('.buy-score').text().replace("选购指数", "");
            }
        });
        console.log("读取第" + (l + 1) + "页列表信息成功")
        //循环读取每一个具体的网页循环读取每一个具体的网页
        for (var i = 0; i < listhref.length; i++) {
            if (listhref[i] != "http:undefined") {
                var Ptable_item = [];
                var finaldata = {
                    名称: "",
                    价格: "",
                    累计评价: "",
                    选购指数: "",
                    //主体
                    品牌: "",
                    系列: "",
                    型号: "",
                    颜色: "",
                    类别: "",
                    // 功能
                    制冷类型: "",
                    匹数: "",
                    "定频/变频": "",
                    能效等级: "",
                    电辅加热: "",
                    "适用面积(平方米)": "",
                    "制冷量(W)": "",
                    "制冷功率(W)": "",
                    "制热量(W)": "",
                    "制热功率(W)": "",
                    "电辅加热功率(W)": "",
                    "内机噪音(dB(A)": "",
                    "外机噪音(dB(A)": "",
                    变频机能效比: "",
                    "循环风量(m3/h)": "",
                    "除湿量(×10-3m3/h)": "",
                    扫风方式: "",
                    //产品特色
                    自动清洁: "",
                    静音设计: "",
                    独立除湿: "",
                    除甲醛: "",
                    其它: "",
                    //规格
                    制冷剂: "",
                    "电压/频率（V/HZ）": "",
                    "内机尺寸（宽x高x深）mm": "",
                    "外机尺寸（宽x高x深）mm": "",
                    "电压/频率（V/HZ）": "",
                    "内机重量（kg）": "",
                    "外机重量（kg)": "",
                    //规格
                    特性: ""
                }
                pageitem = await instance.createPage();
                pageitem.setting('javascriptEnabled', "false");
                status = await pageitem.open(listhref[i]);
                console.log("开始爬取：", listhref[i])

                while (status != "success") {
                    status = await pageitem.open(listhref[i]);
                    await pageitem.close();
                    console.log("网页暂时打不开，重试中..")
                    status = await pageitem.open(listhref[i]);
                }

                await pageitem.on('onResourceRequested', true, function (requestData) {});
                const dcontent = await pageitem.property('content');
                detailcontent = await cheerio.load(dcontent);
                await pageitem.close();
                if (detailcontent(".ellipsis").html() != null) {
                    finaldata.名称 = detailcontent(".ellipsis").text();
                    finaldata.价格 = list价格[i];
                    finaldata.累计评价 = list累计评价[i];
                    finaldata.选购指数 = list选购指数[i];

                    //会有没有详细信息的情况
                    if (detailcontent("div[class=Ptable]").html() != null) {
                        //找到 规格与包装下的有内容
                        detailcontent = cheerio.load(detailcontent("div[class=Ptable]").html());
                        //检出 主体、功能、规格、特性四个内容，有时候特性是没有的，这样用循环读取，下一步可能为3也可能为4
                        await detailcontent('div[class=Ptable-item]').each(function (deatili, elem) {
                            Ptable_item[deatili] = $(this).html();
                        });
                        console.log("读取基本数据成功");
                        // 循环处理三（四）个内容，按dt<->dd读取，希望京东的dt是统一的
                        for (var k = 0; k < Ptable_item.length; k++) {
                            detailcontent = cheerio.load(Ptable_item[k]);
                            detailcontent(".Ptable-tips").remove();
                            detailcontent("h3").remove();
                            var datalistdd = [];
                            var datalistdt = [];

                            await detailcontent("dd").each(function (im, elem) {
                                datalistdd[im] = detailcontent(this).text();
                            });
                            await detailcontent("dt").each(function (im, elem) {
                                datalistdt[im] = detailcontent(this).text();
                            });
                            for (var im = 0; im < datalistdd.length; im++) {
                                finaldata[datalistdt[im]] = datalistdd[im];
                            }
                        }
                    }
                } else { //全球购不太一样
                    finaldata.名称 = detailcontent(".parameter2").children().first().text()
                    finaldata.价格 = list价格[i];
                    finaldata.累计评价 = list累计评价[i];
                    finaldata.选购指数 = list选购指数[i];

                    var Ptable_item = [];
                    await detailcontent("th").remove();
                    var tmp = [];
                    detailcontent(".Ptable").find('td').each(function (i, elem) {
                        tmp[i] = detailcontent(this).text();
                    });
                    for (var d = 0; d < tmp.length; d += 2) {
                        finaldata[tmp[d]] = tmp[d + 1];
                    }
                }
                await csvStream.write({
                    a: finaldata['名称'],
                    b: finaldata['价格'],
                    c: finaldata['累计评价'],
                    d: finaldata['选购指数'],
                    e: finaldata['品牌'],
                    f: finaldata['系列'],
                    g: finaldata['型号'],
                    h: finaldata['颜色'],
                    i: finaldata['类别'],
                    j: finaldata['制冷类型'],
                    k: finaldata['匹数'],
                    l: finaldata['定频/变频'],
                    m: finaldata['能效等级'],
                    n: finaldata['电辅加热'],
                    o: finaldata['适用面积(平方米)'],
                    p: finaldata['制冷量(W)'],
                    q: finaldata['制冷功率(W)'],
                    r: finaldata['制热量(W)'],
                    s: finaldata['制热功率(W)'],
                    t: finaldata['电辅加热功率(W)'],
                    u: finaldata['内机噪音(dB(A)'],
                    v: finaldata['外机噪音(dB(A)'],
                    w: finaldata['变频机能效比'],
                    x: finaldata['循环风量(m3/h)'],
                    y: finaldata['除湿量(×10-3m3/h)'],
                    z: finaldata['扫风方式'],
                    aa: finaldata['自动清洁'],
                    ab: finaldata['静音设计'],
                    ac: finaldata['独立除湿'],
                    ad: finaldata['除甲醛'],
                    ae: finaldata['其它'],
                    af: finaldata['制冷剂'],
                    ag: finaldata['电压/频率（V/HZ）'],
                    ah: finaldata['内机尺寸（宽x高x深）mm'],
                    ai: finaldata['外机尺寸（宽x高x深）mm'],
                    aj: finaldata['电压/频率（V/HZ）'],
                    ak: finaldata['内机重量（kg）'],
                    al: finaldata['内机重量（kg）'],
                    am: finaldata['特性'],
                });
                await console.log("写入第" + (l * 60 + i + 1) + "条数据");
            }
        }
        await instance.exit();
    }
    await csvStream.end();
}

Pa();